#ifndef AUDIT__H
#define AUDIT__H

#include <stdarg.h>
#include <stdio.h>
#include <time.h>

/* Color format */
#ifndef ANSI_COLOR
#define ANSI_COLOR

#define COLOR_RED "\x1b[31m"
#define COLOR_GREEN "\x1b[32m"
#define COLOR_YELLOW "\x1b[33m"
#define COLOR_RESET "\x1b[0m"

#endif // !ANSI_COLOR

int ebpflsm_error(const char *fmt, ...)
{
    char printf_buf[1034];
    va_list args;
    int printed;

    // 获取时间并格式化时间戳
    time_t now = time(NULL);
    struct tm *tm_info = localtime(&now);
    char timestamp[20];
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm_info);

    // 错误前缀
    const char *error_prefix = "[ERROR]: ";
    const char *error_prefix_color = COLOR_RED "[ERROR]: " COLOR_RESET;

    // 生成终端输出的字符串
    int prefix_length_color = snprintf(printf_buf, sizeof(printf_buf), "%s", error_prefix_color);

    va_start(args, fmt);
    // 使用 vsnprintf 避免潜在的缓冲区溢出
    printed = vsnprintf(printf_buf + prefix_length_color, sizeof(printf_buf) - prefix_length_color, fmt, args);
    va_end(args);

    // 如果 vsnprintf 返回的值大于或等于缓冲区大小，则输出被截断
    if (printed >= sizeof(printf_buf) - prefix_length_color)
    {
        printf_buf[sizeof(printf_buf) - 1] = '\0'; // 确保字符串结束符
        printed = sizeof(printf_buf) - prefix_length_color - 1;
    }

    if (config.log_level == AUDIT_LEVEL_DEBUG)
    {
        puts(printf_buf); // 输出到终端带颜色编码
    }

    if (config.log_level == AUDIT_LEVEL_LOG)
    {
        // 生成日志文件名
        char log_filename[256];
        snprintf(log_filename, sizeof(log_filename), "%s/logfile_%04d-%02d-%02d.log", config.log_path, tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday);

        // 生成写入日志文件的字符串
        char log_buf[1034];
        int log_prefix_length = snprintf(log_buf, sizeof(log_buf), "%s", error_prefix);

        va_start(args, fmt);
        printed = vsnprintf(log_buf + log_prefix_length, sizeof(log_buf) - log_prefix_length, fmt, args);
        va_end(args);

        // 写入日志文件
        FILE *log_file = fopen(log_filename, "a");
        if (log_file)
        {
            fprintf(log_file, "[%s] %s\n", timestamp, log_buf);
            fclose(log_file);
        }
        else
        {
            printf("打开日志文件失败: %s\n", log_filename);
        }
    }

    return printed; // 返回格式化后的文本长度（不包括前缀）
}

int ebpflsm_info(const char *fmt, ...)
{
    char printf_buf[1034];
    va_list args;
    int printed;

    // 获取时间并格式化时间戳
    time_t now = time(NULL);
    struct tm *tm_info = localtime(&now);
    char timestamp[20];
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm_info);

    // 错误前缀
    const char *info_prefix = "[INFO]: ";
    const char *info_prefix_color = COLOR_YELLOW "[INFO]: " COLOR_RESET;

    // 生成终端输出的字符串
    int prefix_length_color = snprintf(printf_buf, sizeof(printf_buf), "%s", info_prefix_color);

    va_start(args, fmt);
    // 使用 vsnprintf 避免潜在的缓冲区溢出
    printed = vsnprintf(printf_buf + prefix_length_color, sizeof(printf_buf) - prefix_length_color, fmt, args);
    va_end(args);

    // 如果 vsnprintf 返回的值大于或等于缓冲区大小，则输出被截断
    if (printed >= sizeof(printf_buf) - prefix_length_color)
    {
        printf_buf[sizeof(printf_buf) - 1] = '\0'; // 确保字符串结束符
        printed = sizeof(printf_buf) - prefix_length_color - 1;
    }

    if (config.log_level == AUDIT_LEVEL_DEBUG)
    {
        puts(printf_buf); // 输出到终端带颜色编码
    }

    if (config.log_level == AUDIT_LEVEL_LOG)
    {
        // 生成日志文件名
        char log_filename[256];
        snprintf(log_filename, sizeof(log_filename), "%s/logfile_%04d-%02d-%02d.log", config.log_path, tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday);

        // 生成写入日志文件的字符串
        char log_buf[1034];
        int log_prefix_length = snprintf(log_buf, sizeof(log_buf), "%s", info_prefix);

        va_start(args, fmt);
        printed = vsnprintf(log_buf + log_prefix_length, sizeof(log_buf) - log_prefix_length, fmt, args);
        va_end(args);

        // 写入日志文件
        FILE *log_file = fopen(log_filename, "a");
        if (log_file)
        {
            fprintf(log_file, "[%s] %s\n", timestamp, log_buf);
            fclose(log_file);
        }
        else
        {
            printf("打开日志文件失败: %s\n", log_filename);
        }
    }

    return printed; // 返回格式化后的文本长度（不包括前缀）
}

int ebpflsm_normal(const char *fmt, ...)
{
    char printf_buf[1034];
    va_list args;
    int printed;

    // 获取时间并格式化时间戳
    time_t now = time(NULL);
    struct tm *tm_info = localtime(&now);
    char timestamp[20];
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm_info);

    // 错误前缀
    const char *normal_prefix = "[NORMAL]: ";
    const char *normal_prefix_color = COLOR_GREEN "[NORMAL]: " COLOR_RESET;

    // 生成终端输出的字符串
    int prefix_length_color = snprintf(printf_buf, sizeof(printf_buf), "%s", normal_prefix_color);

    va_start(args, fmt);
    // 使用 vsnprintf 避免潜在的缓冲区溢出
    printed = vsnprintf(printf_buf + prefix_length_color, sizeof(printf_buf) - prefix_length_color, fmt, args);
    va_end(args);

    // 如果 vsnprintf 返回的值大于或等于缓冲区大小，则输出被截断
    if (printed >= sizeof(printf_buf) - prefix_length_color)
    {
        printf_buf[sizeof(printf_buf) - 1] = '\0'; // 确保字符串结束符
        printed = sizeof(printf_buf) - prefix_length_color - 1;
    }

    if (config.log_level == AUDIT_LEVEL_DEBUG)
    {
        puts(printf_buf); // 输出到终端带颜色编码
    }

    if (config.log_level == AUDIT_LEVEL_LOG)
    {
        // 生成日志文件名
        char log_filename[256];
        snprintf(log_filename, sizeof(log_filename), "%s/logfile_%04d-%02d-%02d.log", config.log_path, tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday);

        // 生成写入日志文件的字符串
        char log_buf[1034];
        int log_prefix_length = snprintf(log_buf, sizeof(log_buf), "%s", normal_prefix);

        va_start(args, fmt);
        printed = vsnprintf(log_buf + log_prefix_length, sizeof(log_buf) - log_prefix_length, fmt, args);
        va_end(args);

        // 写入日志文件
        FILE *log_file = fopen(log_filename, "a");
        if (log_file)
        {
            fprintf(log_file, "[%s] %s\n", timestamp, log_buf);
            fclose(log_file);
        }
        else
        {
            printf("打开日志文件失败: %s\n", log_filename);
        }
    }

    return printed; // 返回格式化后的文本长度（不包括前缀）
}

#endif // !AUDIT__H